// utils/errorHandler.js
// 全局错误处理和用户反馈系统

/**
 * 错误类型枚举
 */
const ERROR_TYPES = {
  NETWORK: 'network',
  STORAGE: 'storage',
  VALIDATION: 'validation',
  PERMISSION: 'permission',
  SYSTEM: 'system',
  USER: 'user'
}

/**
 * 错误级别枚举
 */
const ERROR_LEVELS = {
  INFO: 'info',
  WARNING: 'warning',
  ERROR: 'error',
  FATAL: 'fatal'
}

/**
 * 用户反馈类型
 */
const FEEDBACK_TYPES = {
  SUCCESS: 'success',
  ERROR: 'error',
  WARNING: 'warning',
  INFO: 'info',
  LOADING: 'loading'
}

/**
 * 错误处理器类
 */
class ErrorHandler {
  /**
   * 处理错误
   * @param {Error|string} error - 错误对象或错误信息
   * @param {string} type - 错误类型
   * @param {string} level - 错误级别
   * @param {Object} context - 错误上下文
   */
  static handleError(error, type = ERROR_TYPES.SYSTEM, level = ERROR_LEVELS.ERROR, context = {}) {
    try {
      // 记录错误
      this.logError(error, type, level, context)
      
      // 根据错误级别决定处理方式
      switch (level) {
        case ERROR_LEVELS.INFO:
          this.showInfo(this.getErrorMessage(error))
          break
        case ERROR_LEVELS.WARNING:
          this.showWarning(this.getErrorMessage(error))
          break
        case ERROR_LEVELS.ERROR:
          this.showError(this.getErrorMessage(error))
          break
        case ERROR_LEVELS.FATAL:
          this.showFatalError(this.getErrorMessage(error))
          break
      }
      
      // 发送错误统计（可选）
      this.reportError(error, type, level, context)
    } catch (handlerError) {
      console.error('错误处理器自身发生错误:', handlerError)
      wx.showToast({
        title: '系统异常',
        icon: 'error'
      })
    }
  }

  /**
   * 记录错误日志
   */
  static logError(error, type, level, context) {
    const errorInfo = {
      timestamp: new Date().toISOString(),
      error: this.getErrorMessage(error),
      type,
      level,
      context,
      stack: error instanceof Error ? error.stack : null,
      userAgent: wx.getSystemInfoSync()
    }
    
    console.error('错误日志:', errorInfo)
    
    // 保存到本地存储（可选）
    this.saveErrorLog(errorInfo)
  }

  /**
   * 保存错误日志到本地
   */
  static saveErrorLog(errorInfo) {
    try {
      const logs = wx.getStorageSync('error_logs') || []
      logs.push(errorInfo)
      
      // 只保留最近50条错误日志
      if (logs.length > 50) {
        logs.splice(0, logs.length - 50)
      }
      
      wx.setStorageSync('error_logs', logs)
    } catch (error) {
      console.error('保存错误日志失败:', error)
    }
  }

  /**
   * 获取错误消息
   */
  static getErrorMessage(error) {
    if (typeof error === 'string') {
      return error
    }
    
    if (error instanceof Error) {
      return error.message
    }
    
    return '未知错误'
  }

  /**
   * 显示信息提示
   */
  static showInfo(message) {
    wx.showToast({
      title: message,
      icon: 'none',
      duration: 2000
    })
  }

  /**
   * 显示警告提示
   */
  static showWarning(message) {
    wx.showToast({
      title: message,
      icon: 'none',
      duration: 3000
    })
  }

  /**
   * 显示错误提示
   */
  static showError(message) {
    wx.showModal({
      title: '错误提示',
      content: message,
      showCancel: false,
      confirmText: '知道了'
    })
  }

  /**
   * 显示致命错误
   */
  static showFatalError(message) {
    wx.showModal({
      title: '严重错误',
      content: `${message}\n\n建议重启应用或联系技术支持`,
      showCancel: true,
      confirmText: '重启应用',
      cancelText: '稍后处理',
      success: (res) => {
        if (res.confirm) {
          wx.reLaunch({
            url: '/pages/index/index'
          })
        }
      }
    })
  }

  /**
   * 上报错误统计
   */
  static reportError(error, type, level, context) {
    // 这里可以集成第三方错误监控服务
    // 例如：Sentry, Bugsnag 等
    console.log('错误统计上报:', {
      error: this.getErrorMessage(error),
      type,
      level,
      context
    })
  }

  /**
   * 获取错误日志
   */
  static getErrorLogs() {
    try {
      return wx.getStorageSync('error_logs') || []
    } catch (error) {
      console.error('获取错误日志失败:', error)
      return []
    }
  }

  /**
   * 清除错误日志
   */
  static clearErrorLogs() {
    try {
      wx.removeStorageSync('error_logs')
      return true
    } catch (error) {
      console.error('清除错误日志失败:', error)
      return false
    }
  }
}

/**
 * 用户反馈系统
 */
class FeedbackManager {
  /**
   * 显示成功反馈
   */
  static showSuccess(message, duration = 2000) {
    wx.showToast({
      title: message,
      icon: 'success',
      duration
    })
  }

  /**
   * 显示错误反馈
   */
  static showError(message, duration = 3000) {
    wx.showToast({
      title: message,
      icon: 'error',
      duration
    })
  }

  /**
   * 显示警告反馈
   */
  static showWarning(message, duration = 3000) {
    wx.showToast({
      title: message,
      icon: 'none',
      duration
    })
  }

  /**
   * 显示信息反馈
   */
  static showInfo(message, duration = 2000) {
    wx.showToast({
      title: message,
      icon: 'none',
      duration
    })
  }

  /**
   * 显示加载反馈
   */
  static showLoading(message = '加载中...') {
    wx.showLoading({
      title: message,
      mask: true
    })
  }

  /**
   * 隐藏加载反馈
   */
  static hideLoading() {
    wx.hideLoading()
  }

  /**
   * 显示操作确认对话框
   */
  static showConfirm(options = {}) {
    const {
      title = '确认操作',
      content = '确定要执行此操作吗？',
      confirmText = '确定',
      cancelText = '取消',
      confirmColor = '#3cc51f',
      onConfirm = () => {},
      onCancel = () => {}
    } = options

    return new Promise((resolve) => {
      wx.showModal({
        title,
        content,
        showCancel: true,
        confirmText,
        cancelText,
        confirmColor,
        success: (res) => {
          if (res.confirm) {
            onConfirm()
            resolve(true)
          } else {
            onCancel()
            resolve(false)
          }
        }
      })
    })
  }

  /**
   * 显示操作选择列表
   */
  static showActionSheet(options = {}) {
    const {
      itemList = [],
      onSelect = () => {},
      onCancel = () => {}
    } = options

    return new Promise((resolve) => {
      wx.showActionSheet({
        itemList,
        success: (res) => {
          onSelect(res.tapIndex, itemList[res.tapIndex])
          resolve(res.tapIndex)
        },
        fail: () => {
          onCancel()
          resolve(-1)
        }
      })
    })
  }

  /**
   * 振动反馈
   */
  static vibrate(type = 'short') {
    try {
      if (type === 'long') {
        wx.vibrateLong()
      } else {
        wx.vibrateShort()
      }
    } catch (error) {
      console.log('振动反馈失败:', error)
    }
  }

  /**
   * 显示自定义反馈
   */
  static showCustomFeedback(options = {}) {
    const {
      type = FEEDBACK_TYPES.INFO,
      message = '',
      duration = 2000,
      showVibrate = false
    } = options

    if (showVibrate) {
      this.vibrate()
    }

    switch (type) {
      case FEEDBACK_TYPES.SUCCESS:
        this.showSuccess(message, duration)
        break
      case FEEDBACK_TYPES.ERROR:
        this.showError(message, duration)
        break
      case FEEDBACK_TYPES.WARNING:
        this.showWarning(message, duration)
        break
      case FEEDBACK_TYPES.INFO:
        this.showInfo(message, duration)
        break
      case FEEDBACK_TYPES.LOADING:
        this.showLoading(message)
        break
    }
  }
}

/**
 * 网络错误处理
 */
class NetworkErrorHandler {
  /**
   * 处理网络请求错误
   */
  static handleNetworkError(error, context = {}) {
    let message = '网络连接异常'
    
    if (error.errMsg) {
      if (error.errMsg.includes('timeout')) {
        message = '网络请求超时'
      } else if (error.errMsg.includes('fail')) {
        message = '网络请求失败'
      }
    }
    
    ErrorHandler.handleError(error, ERROR_TYPES.NETWORK, ERROR_LEVELS.ERROR, context)
  }

  /**
   * 检查网络状态
   */
  static checkNetworkStatus() {
    return new Promise((resolve) => {
      wx.getNetworkType({
        success: (res) => {
          resolve({
            isConnected: res.networkType !== 'none',
            networkType: res.networkType
          })
        },
        fail: () => {
          resolve({
            isConnected: false,
            networkType: 'none'
          })
        }
      })
    })
  }
}

/**
 * 存储错误处理
 */
class StorageErrorHandler {
  /**
   * 处理存储错误
   */
  static handleStorageError(error, operation = 'unknown', context = {}) {
    let message = '数据存储异常'
    
    if (operation === 'read') {
      message = '数据读取失败'
    } else if (operation === 'write') {
      message = '数据保存失败'
    } else if (operation === 'delete') {
      message = '数据删除失败'
    }
    
    ErrorHandler.handleError(error, ERROR_TYPES.STORAGE, ERROR_LEVELS.ERROR, {
      operation,
      ...context
    })
  }

  /**
   * 检查存储空间
   */
  static checkStorageSpace() {
    return new Promise((resolve) => {
      wx.getStorageInfo({
        success: (res) => {
          resolve({
            keys: res.keys,
            currentSize: res.currentSize,
            limitSize: res.limitSize,
            usage: res.currentSize / res.limitSize
          })
        },
        fail: (error) => {
          this.handleStorageError(error, 'check')
          resolve(null)
        }
      })
    })
  }
}

export {
  ErrorHandler,
  FeedbackManager,
  NetworkErrorHandler,
  StorageErrorHandler,
  ERROR_TYPES,
  ERROR_LEVELS,
  FEEDBACK_TYPES
} 